package com.imy.lua.udmapping.node;

import android.content.Context;
import android.graphics.Rect;
import android.util.Log;
import android.view.accessibility.AccessibilityNodeInfo;

import androidx.annotation.CallSuper;
import androidx.annotation.NonNull;

import com.immomo.mls.LuaViewManager;
import com.immomo.mls.MLSBuilder;
import com.immomo.mls.utils.convert.ConvertUtils;
import com.immomo.mls.wrapper.ILuaValueGetter;
import com.imy.common.util.ALog;
import com.imy.common.util.ClipboardUtils;
import com.imy.lua.LuaCore;

import org.luaj.vm2.Globals;
import org.luaj.vm2.LuaBoolean;
import org.luaj.vm2.LuaNumber;
import org.luaj.vm2.LuaString;
import org.luaj.vm2.LuaUserdata;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.utils.LuaApiUsed;


/**
 * Created by MLN Template 注册方法： Register.newUDHolder(UDNodeInfo.LUA_CLASS_NAME, UDNodeInfo.class, true)
 */
@LuaApiUsed
public class UDNodeInfo extends LuaUserdata<AccessibilityNodeInfo> {
  /**
   * Lua类名
   */
  public static final String LUA_CLASS_NAME = "Node";
  /**
   * 所有Bridge的名称 且Java方法必须有{@link LuaApiUsed}注解
   */
  public static final String[] methods = {
      "getClassName",
      "centerX",
      "centerY",
      "getWidth",
      "getHeight",
      "clicked",
      "canClicked",
      "isEnable",
      "getId",
      "setText",
      "getParent",
  };

  //<editor-fold desc="Constructors">

  /**
   * 提供给Lua的构造函数 必须存在
   *
   * @param L 虚拟机底层地址
   * @param v 初始化参数，非空，但长度可能为0
   */
  @LuaApiUsed
  protected UDNodeInfo(long L, @NonNull LuaValue[] v) {
    super(L, v);
    /// 必须完成包裹对象的初始化
  }

  /**
   * 提供给Java的构造函数
   *
   * @param g 虚拟机
   * @param o 初始化对象
   */
  @LuaApiUsed
  public UDNodeInfo(@NonNull Globals g, AccessibilityNodeInfo o) {
    super(g, o);
  }
  //</editor-fold>

  @LuaApiUsed
  public LuaValue[] getClassName(LuaValue[] luaValues) {
    ALog.i("getClassName:");
    return varargsOf(LuaString.valueOf(javaUserdata.getClassName().toString()));
  }

  @LuaApiUsed
  public LuaValue[] centerX(LuaValue[] luaValues) {
    Rect rect = new Rect();

    javaUserdata.getBoundsInScreen(rect);
    ALog.i("centerX:" + rect.centerX());
    return varargsOf(LuaNumber.valueOf(rect.centerX()));
  }

  @LuaApiUsed
  public LuaValue[] centerY(LuaValue[] luaValues) {
    Rect rect = new Rect();
    javaUserdata.getBoundsInScreen(rect);
    return varargsOf(LuaNumber.valueOf(rect.centerY()));
  }

  @LuaApiUsed
  public LuaValue[] getWidth(LuaValue[] luaValues) {
    Rect rect = new Rect();
    javaUserdata.getBoundsInScreen(rect);
    int width = rect.right - rect.left;
    return varargsOf(LuaNumber.valueOf(width));
  }

  @LuaApiUsed
  public LuaValue[] isEnable(LuaValue[] luaValues) {
    boolean enabled = javaUserdata.isEnabled();
    return varargsOf(LuaBoolean.valueOf(enabled));
  }

  @LuaApiUsed
  public LuaValue[] getHeight(LuaValue[] luaValues) {
    Rect rect = new Rect();
    javaUserdata.getBoundsInScreen(rect);
    int height = rect.bottom - rect.top;
    return varargsOf(LuaNumber.valueOf(height));
  }

  @LuaApiUsed
  public LuaValue[] clicked(LuaValue[] luaValues) {
    javaUserdata.performAction(AccessibilityNodeInfo.ACTION_CLICK);
    //Rect rect = new Rect();
    //javaUserdata.getBoundsInScreen(rect);
    //int x = rect.centerX();
    //int y = rect.centerY();
    return varargsOf(LuaValue.Nil());
  }

  @LuaApiUsed
  public LuaValue[] setText(LuaValue[] luaValues) {
    if (luaValues.length > 0) {
      String s = luaValues[0].toJavaString();
      ClipboardUtils.setText(LuaCore.get().getContext(), s);
      javaUserdata.performAction(AccessibilityNodeInfo.ACTION_FOCUS);
      javaUserdata.performAction(AccessibilityNodeInfo.ACTION_PASTE);
    }
    return varargsOf(LuaValue.Nil());
  }

  @LuaApiUsed
  public LuaValue[] canClicked(LuaValue[] luaValues) {
    boolean clickable = javaUserdata.isClickable();
    return varargsOf(LuaBoolean.valueOf(clickable));
  }

  @LuaApiUsed
  public LuaValue[] getParent(LuaValue[] luaValues) {
    AccessibilityNodeInfo parent = javaUserdata.getParent();
    UDNodeInfo udNodeInfo = new UDNodeInfo(globals, parent);
    return varargsOf(ConvertUtils.toLuaValue(globals, udNodeInfo));
  }

  @LuaApiUsed
  public LuaValue[] getId(LuaValue[] luaValues) {
    return varargsOf(LuaString.valueOf(javaUserdata.getViewIdResourceName()));
  }

  /**
   * 获取上下文，一般为Activity
   */
  protected Context getContext() {
    LuaViewManager m = (LuaViewManager) getGlobals().getJavaUserdata();
    return m != null ? m.context : null;
  }

  //<editor-fold desc="Bridge API">

  //</editor-fold>

  //<editor-fold desc="Other">

  /**
   * 此对象被Lua GC时调用，可不实现 可做相关释放操作
   */
  @CallSuper
  @Override
  protected void __onLuaGc() {
    javaUserdata = null;
    super.__onLuaGc();
  }

  /**
   * Lua判断相等时，可能会调用此方法
   * 可通过实现{@link #equals(Object)}来实现
   */
  //@Override
  //protected boolean __onLuaEq(Object other) { }

  /**
   * 若{@link #__onLuaEq}默认实现，则Lua判断相等时，可能调用此方法
   */
  //@Override
  //public boolean equals(Object o) { }
  //</editor-fold>

  //<editor-fold desc="Auto Convert">
  /**
   * 将Lua类型自动转换为Java类型，一般在基础类中使用，或选择默认转换方式
   * 注册方法：
   * @see com.immomo.mls.MLSBuilder#registerCovert(MLSBuilder.CHolder...)
   * @see MLSBuilder.CHolder
   */
    /*public static final IJavaObjectGetter<UDNodeInfo, AccessibilityNodeInfo> J = new IJavaObjectGetter<UDNodeInfo, AccessibilityNodeInfo>() {
        @Override
        public AccessibilityNodeInfo getJavaObject(UDNodeInfo lv) {
            return lv.getJavaUserdata();
        }
    };*/

  /**
   * 将Java类型转换为Lua类型，一般在基础类中使用，或选择默认转换方式 注册方法：
   *
   * @see com.immomo.mls.MLSBuilder#registerCovert(MLSBuilder.CHolder...)
   * @see MLSBuilder.CHolder
   */
  public static final ILuaValueGetter<UDNodeInfo, AccessibilityNodeInfo> L = new ILuaValueGetter<UDNodeInfo, AccessibilityNodeInfo>() {
    @Override
    public UDNodeInfo newInstance(Globals g, AccessibilityNodeInfo obj) {
      return new UDNodeInfo(g, obj);
    }
  };

  //</editor-fold>
}
